package com.mooco.dongba.sys.service.impl;

import com.mooco.dongba.common.exception.ServiceException;
import com.mooco.dongba.common.pojo.PageObject;
import com.mooco.dongba.sys.dao.SysUserDao;
import com.mooco.dongba.sys.dao.SysUserRoleDao;
import com.mooco.dongba.sys.pojo.SysUser;
import com.mooco.dongba.sys.pojo.SysUserDeptVo;
import com.mooco.dongba.sys.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
@Transactional(timeout = 30,
        readOnly = true,
        isolation = Isolation.READ_COMMITTED,
        rollbackFor = Throwable.class,
        propagation = Propagation.REQUIRED)
public class SysUserServiceImpl implements SysUserService {
    @Autowired
    private SysUserDao sysUserDao;

    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    @Override
    @Transactional(readOnly = true)
    public PageObject<SysUserDeptVo> findPageObject(String username, Integer pageCurrent) {
        // 1、参数校验
        if (pageCurrent == null || pageCurrent <= 0) {
            throw new IllegalArgumentException("当前页码值无效");
        }

        // 2、获取总记录数
        int rowCount = sysUserDao.getRowCount(username);
        if (rowCount == 0)
            throw new ServiceException("没有找到对应的记录");
        int pageSize = 2;
        int startIndex = (pageCurrent - 1) * pageSize;

        // 3、获取分页数据，并返回
        List<SysUserDeptVo> records = sysUserDao.findPageObjects(username, startIndex, pageSize);
        return new PageObject<SysUserDeptVo>(rowCount, pageSize, pageCurrent, records);
    }

    @Override
    public int valid(Integer id, Integer valid) {
        // 1、参数合法性校验
        if (id == null || id <= 0)
            throw new IllegalArgumentException("参数不合法：id=" + id);
        if (valid == null || (valid != 0 && valid != 1))
            throw new IllegalArgumentException("参数不合法：valid=" + valid);

        // 2、更新数据，并返回
        int rows = sysUserDao.validById(id, valid, "admin");
        if (rows == 0)
            throw new ServiceException("此记录可能已经不存在");
        return rows;
    }

    @Override
    public int saveObject(SysUser entity, Integer[] roleIds) {
        // 1、参数校验
        if (entity == null)
            throw new IllegalArgumentException("保存的对象不能为空");
        if (entity.getUsername() == null || "".equals(entity.getUsername()))
            throw new IllegalArgumentException("用户名不能为空");
        if (entity.getPassword() == null || "".equals(entity.getPassword()))
            throw new IllegalArgumentException("密码不能为空");
        if (roleIds == null || roleIds.length == 0)
            throw new IllegalArgumentException("必须为用户赋予角色");

        // 2、密码加密
        String salt = UUID.randomUUID().toString();
        SimpleHash sh = new SimpleHash("MD5", entity.getPassword(), salt, 1);
        entity.setSalt(salt);
        entity.setPassword(sh.toHex());

        // 3、插入用户信息和用户角色信息
        int rows = sysUserDao.insertObject(entity);
        sysUserRoleDao.insertObjects(entity.getId(), roleIds);
        return rows;
    }

    @Override
    public Map<String, Object> findObjectById(Integer id) {
        // 1、参数校验
        if (id == null || id <= 0)
            throw new IllegalArgumentException("请先选择");

        Map<String, Object> map = new HashMap<>();
        // 2、获取用户信息
        SysUserDeptVo user = sysUserDao.findObjectById(id);
        if (user == null)
            throw new ServiceException("此用户可能已经不存在");

        // 3、获取用户的角色信息
        List<Integer> roleIds = sysUserRoleDao.findRoleIdsByUserId(id);
        map.put("user", user);
        map.put("roleIds", roleIds);
        return map;
    }

    @Override
    @RequiresPermissions("sys:user:update")
    public int updateObject(SysUser entity, Integer[] roleIds) {
        // 1、参数校验
        if (entity == null)
            throw new IllegalArgumentException("保存的对象不能为空");
        if (entity.getUsername() == null || "".equals(entity.getUsername()))
            throw new IllegalArgumentException("用户名不能为空");
        if (roleIds == null || roleIds.length == 0)
            throw new IllegalArgumentException("必须为用户赋予角色");

        // 2、更新用户数据
        int rows = sysUserDao.updateObject(entity);
        if (rows == 0)
            throw new ServiceException("此记录可能已经不存在");

        // 3、删除用户角色关系
        sysUserRoleDao.deleteObjectByUserId(entity.getId());

        // 3、更新用户角色关系
        sysUserRoleDao.insertObjects(entity.getId(), roleIds);

        return rows;
    }

    @Override
    public int updatePassword(String password, String newPassword, String cfgPassword) {
        // 1、参数校验
        if (password == null || "".equals(password))
            throw new IllegalArgumentException("原密码不能为空");
        if (newPassword == null || "".equals(newPassword))
            throw new IllegalArgumentException("新密码不能为空");
        if (cfgPassword == null || "".equals(cfgPassword))
            throw new IllegalArgumentException("确认密码不能为空");
        if (newPassword != cfgPassword)
            throw new IllegalArgumentException("两次密码输入不一致");

        // 2、利用shiro获取SysUser对象
        SysUser user = (SysUser) SecurityUtils.getSubject().getPrincipal();

        // 3、校验原密码是否正确
        SimpleHash sh = new SimpleHash("MD5", password, user.getSalt(), 1);
        if (user.getPassword() != sh.toHex().toString())
            throw new ServiceException("原密码错误");

        // 4、生成新盐，新密码
        String salt = UUID.randomUUID().toString();
        sh = new SimpleHash("MD5", newPassword, salt, 1);

        // 5、更新数据
        int rows = sysUserDao.updatePassword(sh.toHex(), salt, user.getId());
        if (rows == 0)
            throw new ServiceException("修改失败");
        return rows;
    }
}
